"""
MiniCoder Agent

智能编程助手，可以自主调用工具完成任务。
"""

import json
import re
from typing import Dict, List, Any, Optional

from rich.console import Console
from rich.panel import Panel

from ..ai import AIModel
from ..tools import ToolManager
from .tool_caller import ToolCaller
from .prompt_templates import AgentPrompts

console = Console()


class MiniCoderAgent:
    """MiniCoder AI Agent"""
    
    def __init__(self, ai_model: AIModel, tool_manager: ToolManager):
        """
        初始化 Agent
        
        Args:
            ai_model: AI 模型实例
            tool_manager: 工具管理器实例
        """
        self.ai_model = ai_model
        self.tool_manager = tool_manager
        self.tool_caller = ToolCaller(tool_manager)
        self.conversation_history: List[Dict[str, str]] = []
        
        # 获取可用工具信息
        self.available_tools = self._get_available_tools_info()
        
        # 设置系统提示词
        self.system_prompt = AgentPrompts.get_system_prompt(self.available_tools)
    
    def _get_available_tools_info(self) -> List[Dict[str, Any]]:
        """获取可用工具信息"""
        tools = self.tool_manager.list_tools(enabled_only=True)
        return [
            {
                'name': tool.name,
                'description': tool.description,
                'parameters': tool.get_parameters()
            }
            for tool in tools
        ]
    
    def process_query(self, user_query: str, context: Optional[Dict[str, Any]] = None) -> str:
        """
        处理用户查询
        
        Args:
            user_query: 用户查询
            context: 上下文信息
            
        Returns:
            str: Agent 的响应
        """
        console.print(f"[bold cyan]🤖 MiniCoder Agent 处理查询:[/bold cyan] {user_query}")
        
        # 构建完整的提示词
        full_prompt = self._build_full_prompt(user_query, context)
        
        # 获取 AI 响应
        ai_response = self._get_ai_response(full_prompt)
        
        # 提取并执行工具调用
        tool_calls = self.tool_caller.extract_tool_calls(ai_response)
        
        if tool_calls:
            console.print(f"[blue]🔧 发现 {len(tool_calls)} 个工具调用[/blue]")
            
            # 执行工具调用
            tool_results = self.tool_caller.execute_tool_calls(tool_calls)
            
            # 基于工具结果生成最终响应
            final_response = self._generate_final_response(user_query, ai_response, tool_results)
        else:
            # 没有工具调用，直接返回 AI 响应
            final_response = ai_response
        
        # 保存对话历史
        self.conversation_history.append({
            'user': user_query,
            'agent': final_response,
            'tool_calls': tool_calls
        })
        
        return final_response
    
    def _build_full_prompt(self, user_query: str, context: Optional[Dict[str, Any]] = None) -> str:
        """构建完整的提示词"""
        prompt_parts = [self.system_prompt]
        
        # 添加上下文信息
        if context:
            if 'files' in context:
                prompt_parts.append(f"当前包含的文件: {', '.join(context['files'])}")
            if 'project_path' in context:
                prompt_parts.append(f"当前项目路径: {context['project_path']}")
        
        # 添加对话历史
        if self.conversation_history:
            prompt_parts.append("\n## 对话历史")
            for i, conv in enumerate(self.conversation_history[-3:], 1):  # 只保留最近3轮对话
                prompt_parts.append(f"用户: {conv['user']}")
                prompt_parts.append(f"助手: {conv['agent'][:200]}...")
        
        # 添加当前查询
        prompt_parts.append(f"\n## 当前查询\n用户: {user_query}")
        prompt_parts.append("\n请根据用户的需求，选择合适的工具来获取信息，然后提供准确的回答。")
        
        return "\n".join(prompt_parts)
    
    def _get_ai_response(self, prompt: str) -> str:
        """获取 AI 响应"""
        try:
            return self.ai_model.generate(prompt, stream=False)
        except Exception as e:
            console.print(f"[red]AI 响应生成失败: {e}[/red]")
            return f"抱歉，我无法处理您的请求。错误信息: {e}"
    
    def _generate_final_response(self, user_query: str, initial_response: str, 
                               tool_results: List[Dict[str, Any]]) -> str:
        """基于工具结果生成最终响应"""
        # 构建工具结果摘要
        results_summary = self._build_tool_results_summary(tool_results)
        
        # 构建最终响应提示词
        final_prompt = f"""基于以下工具执行结果，请为用户提供一个完整、准确的回答。

用户查询: {user_query}

初始响应: {initial_response}

工具执行结果:
{results_summary}

请提供一个基于实际工具执行结果的完整回答，包括：
1. 总结工具执行的结果
2. 提供具体的建议或解决方案
3. 如果可能，提供代码示例或具体步骤
4. 指出任何需要注意的问题或限制

请确保回答是基于实际工具执行的结果，而不是猜测。"""
        
        try:
            final_response = self.ai_model.generate(final_prompt, stream=False)
            return final_response
        except Exception as e:
            console.print(f"[red]最终响应生成失败: {e}[/red]")
            return self._fallback_response(user_query, tool_results)
    
    def _build_tool_results_summary(self, tool_results: List[Dict[str, Any]]) -> str:
        """构建工具结果摘要"""
        if not tool_results:
            return "没有工具执行结果"
        
        summary_parts = []
        for result in tool_results:
            tool_name = result['tool_name']
            success = result['success']
            tool_result = result['result']
            
            status = "成功" if success else "失败"
            summary_parts.append(f"工具: {tool_name} ({status})")
            
            if success and 'data' in tool_result:
                data = tool_result['data']
                if isinstance(data, dict):
                    # 处理项目分析工具的结果
                    if tool_name == 'project_analyzer':
                        project_info = data.get('project_info', {})
                        technologies = data.get('technologies', {})
                        statistics = data.get('statistics', {})
                        structure = data.get('structure', {})
                        
                        summary_parts.append(f"  项目名称: {project_info.get('name', '未知')}")
                        summary_parts.append(f"  项目路径: {project_info.get('path', '未知')}")
                        summary_parts.append(f"  是否Git仓库: {'是' if project_info.get('is_git_repo') else '否'}")
                        
                        # 显示项目描述
                        project_description = project_info.get('project_description', '')
                        if project_description:
                            summary_parts.append(f"  项目描述: {project_description}")
                        
                        summary_parts.append(f"  编程语言: {', '.join(technologies.get('languages', []))}")
                        summary_parts.append(f"  框架工具: {', '.join(technologies.get('tools', []))}")
                        summary_parts.append(f"  总文件数: {statistics.get('total_files', 0)}")
                        summary_parts.append(f"  总目录数: {statistics.get('total_directories', 0)}")
                        summary_parts.append(f"  项目大小: {statistics.get('total_size', 0)} 字节")
                        
                        # 显示主要文件类型
                        file_types = statistics.get('file_types', {})
                        if file_types:
                            top_types = sorted(file_types.items(), key=lambda x: x[1], reverse=True)[:5]
                            type_summary = ', '.join([f"{ext}({count})" for ext, count in top_types])
                            summary_parts.append(f"  主要文件类型: {type_summary}")
                    
                    # 处理其他工具的结果
                    elif 'files' in data:
                        summary_parts.append(f"  找到 {len(data['files'])} 个文件")
                    elif 'results' in data:
                        summary_parts.append(f"  找到 {len(data['results'])} 个结果")
                    elif 'total_matches' in data:
                        summary_parts.append(f"  总匹配数: {data['total_matches']}")
                    elif 'structure' in data:
                        structure = data['structure']
                        if isinstance(structure, dict):
                            summary_parts.append(f"  目录数: {len(structure.get('directories', []))}")
                            summary_parts.append(f"  文件数: {len(structure.get('files', []))}")
                    
                    if 'message' in tool_result:
                        summary_parts.append(f"  消息: {tool_result['message']}")
                else:
                    summary_parts.append(f"  结果: {str(data)[:100]}...")
            else:
                summary_parts.append(f"  错误: {tool_result.get('error', '未知错误')}")
        
        return "\n".join(summary_parts)
    
    def _fallback_response(self, user_query: str, tool_results: List[Dict[str, Any]]) -> str:
        """备用响应（当 AI 无法生成最终响应时）"""
        response_parts = ["基于工具执行的结果，我为您提供以下信息：\n"]
        
        for result in tool_results:
            if result['success']:
                tool_name = result['tool_name']
                tool_result = result['result']
                
                response_parts.append(f"**{tool_name} 工具执行成功：**")
                
                if 'data' in tool_result:
                    data = tool_result['data']
                    if isinstance(data, dict):
                        # 处理项目分析工具的结果
                        if tool_name == 'project_analyzer':
                            project_info = data.get('project_info', {})
                            technologies = data.get('technologies', {})
                            statistics = data.get('statistics', {})
                            
                            response_parts.append(f"- 项目名称: {project_info.get('name', '未知')}")
                            response_parts.append(f"- 项目路径: {project_info.get('path', '未知')}")
                            response_parts.append(f"- 是否Git仓库: {'是' if project_info.get('is_git_repo') else '否'}")
                            
                            # 显示项目描述
                            project_description = project_info.get('project_description', '')
                            if project_description:
                                response_parts.append(f"- 项目描述: {project_description}")
                            
                            response_parts.append(f"- 编程语言: {', '.join(technologies.get('languages', []))}")
                            response_parts.append(f"- 框架工具: {', '.join(technologies.get('tools', []))}")
                            response_parts.append(f"- 总文件数: {statistics.get('total_files', 0)}")
                            response_parts.append(f"- 总目录数: {statistics.get('total_directories', 0)}")
                            response_parts.append(f"- 项目大小: {statistics.get('total_size', 0)} 字节")
                            
                            # 显示主要文件类型
                            file_types = statistics.get('file_types', {})
                            if file_types:
                                top_types = sorted(file_types.items(), key=lambda x: x[1], reverse=True)[:5]
                                type_summary = ', '.join([f"{ext}({count})" for ext, count in top_types])
                                response_parts.append(f"- 主要文件类型: {type_summary}")
                        
                        # 处理其他工具的结果
                        elif 'files' in data:
                            response_parts.append(f"- 找到 {len(data['files'])} 个文件")
                        elif 'results' in data:
                            response_parts.append(f"- 找到 {len(data['results'])} 个结果")
                        elif 'total_matches' in data:
                            response_parts.append(f"- 总匹配数: {data['total_matches']}")
                        elif 'structure' in data:
                            structure = data['structure']
                            if isinstance(structure, dict):
                                response_parts.append(f"- 目录数: {len(structure.get('directories', []))}")
                                response_parts.append(f"- 文件数: {len(structure.get('files', []))}")
                
                if 'message' in tool_result:
                    response_parts.append(f"- {tool_result['message']}")
            else:
                response_parts.append(f"**{result['tool_name']} 工具执行失败：** {result['result'].get('error', '未知错误')}")
        
        return "\n".join(response_parts)
    
    def suggest_tools(self, query: str) -> List[str]:
        """为查询建议合适的工具"""
        return self.tool_caller.suggest_tools_for_query(query)
    
    def get_conversation_history(self) -> List[Dict[str, str]]:
        """获取对话历史"""
        return self.conversation_history.copy()
    
    def clear_history(self) -> None:
        """清空对话历史"""
        self.conversation_history.clear()
        self.tool_caller.clear_history()
        console.print("[yellow]对话历史已清空[/yellow]")
    
    def get_agent_status(self) -> Dict[str, Any]:
        """获取 Agent 状态"""
        return {
            'available_tools': len(self.available_tools),
            'conversation_turns': len(self.conversation_history),
            'tool_calls_made': len(self.tool_caller.call_history),
            'ai_model': self.ai_model.get_model_info()
        }
    
    def display_status(self) -> None:
        """显示 Agent 状态"""
        status = self.get_agent_status()
        
        status_panel = Panel(
            f"可用工具: {status['available_tools']}\n"
            f"对话轮数: {status['conversation_turns']}\n"
            f"工具调用次数: {status['tool_calls_made']}\n"
            f"AI 模型: {status['ai_model']['model']}",
            title="🤖 MiniCoder Agent 状态",
            border_style="blue"
        )
        console.print(status_panel)
